dp | 记忆化搜索
LeetCode 2786. 访问数组中的位置使分数最大
给你一个下标从 0 开始的整数数组 nums 和一个正整数 x 。
你 一开始 在数组的位置 0 处,你可以按照下述规则访问数组中的其他位置:
- 如果你当前在位置
i,那么你可以移动到满足i < j的 任意 位置j。 - 对于你访问的位置
i,你可以获得分数nums[i]。 - 如果你从位置
i移动到位置j且nums[i]和nums[j]的 奇偶性 不同,那么你将失去分数x。
请你返回你能得到的 最大 得分之和。
注意 ,你一开始的分数为 nums[0] 。
示例 1:
输入:nums = [2,3,6,1,9,2], x = 5
输出:13
解释:我们可以按顺序访问数组中的位置:0 -> 2 -> 3 -> 4 。
对应位置的值为 2 ,6 ,1 和 9 。因为 6 和 1 的奇偶性不同,所以下标从 2 -> 3 让你失去 x = 5 分。
总得分为:2 + 6 + 1 + 9 - 5 = 13 。示例 2:
输入:nums = [2,4,6,8], x = 3
输出:20
解释:数组中的所有元素奇偶性都一样,所以我们可以将每个元素都访问一次,而且不会失去任何分数。
总得分为:2 + 4 + 6 + 8 = 20 。提示:
- 2 <= nums.length <= 10^5
- 1 <= nums[i], x <= 10^6
python
# dp 选或不选
'''
1. 杖举选哪个 选或不选
不需要知道精确的信息:nums[i]
只需要知道 nums[i] 的奇偶性
杖举选哪个 适用于需要完全知道子序列相邻两数的信息
最长递增子序列 O(n^2)
选或不选 1. 适用于子序列相邻数字无关
2. 子序列相邻数字弱关联(奇偶性就只需要知道 0 或 1 的信息)
'''
class Solution:
def maxScore(self, nums: List[int], x: int) -> int:
n = len(nums)
f = [-inf, -inf]
f[nums[0] & 1] = nums[0]
for i in range(1, n):
d = nums[i] & 1
f[d] = max(f[d] + nums[i], f[d ^ 1] + nums[i] - x)
return max(f[0], f[1])python
# 记忆化搜索
'''
1. 杖举选哪个 选或不选
不需要知道精确的信息:nums[i]
只需要知道 nums[i] 的奇偶性
杖举选哪个 适用于需要完全知道子序列相邻两数的信息
最长递增子序列 O(n^2)
选或不选 1. 适用于子序列相邻数字无关
2. 子序列相邻数字弱关联(奇偶性就只需要知道 0 或 1 的信息)
'''
class Solution:
def maxScore(self, nums: List[int], x: int) -> int:
n = len(nums)
@cache
def dfs(i: int, j: int) -> int:
if i == n:
return 0
v = nums[i]
res = dfs(i + 1, v & 1) + v
if v & 1 != j:
res -= x
return max(res, dfs(i + 1, j))
return dfs(1, nums[0] & 1) + nums[0]cpp
class Solution {
public:
// 记忆化搜索
int n, x;
vector<int> nums;
long long dp[100001][2];
long long dfs(int i, int j) {
if (i == n)
return 0;
if (dp[i][j] != -1)
return dp[i][j];
long long res = INT_MIN / 2;
// 选 或 不选
if (j != (nums[i] & 1))
res = max(res, dfs(i + 1, nums[i] & 1) + nums[i] - x);
else
res = max(res, dfs(i + 1, nums[i] & 1) + nums[i]);
res = max(res, dfs(i + 1, j));
dp[i][j] = res;
return res;
}
long long maxScore(vector<int>& nums, int x) {
n = nums.size();
this->nums = nums;
this->x = x;
memset(dp, -1, sizeof(dp));
return dfs(1, nums[0] & 1) + nums[0];
}
};